﻿namespace Pub.Class
{
    using Microsoft.CSharp;
    using System;
    using System.CodeDom;
    using System.CodeDom.Compiler;
    using System.Collections;
    using System.IO;
    using System.Net;
    using System.Text;
    using System.Web.Services.Description;
    using System.Xml;

    public static class WebService
    {
        private static Hashtable _xmlNamespaces = new Hashtable();
        private static readonly ISafeDictionary<string, Type> WSProxyTypeDictionary = new SafeDictionarySlim<string, Type>();

        public static string DynamicWebService(string url, string className, string methodName, Hashtable parms)
        {
            object[] args = new object[parms.Keys.Count];
            int index = 0;
            foreach (string str in parms.Keys)
            {
                args[index] = parms[str];
                index++;
            }
            return InvokeWebService(url, className, methodName, args).ToString();
        }

        private static byte[] EncodeParamsToSoap(Hashtable paras, string xmlNS, string methodName)
        {
            XmlDocument document = new XmlDocument();
            document.LoadXml("<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"></soap:Envelope>");
            XmlDeclaration newChild = document.CreateXmlDeclaration("1.0", "utf-8", null);
            document.InsertBefore(newChild, document.DocumentElement);
            XmlElement element = document.CreateElement("soap", "Body", "http://schemas.xmlsoap.org/soap/envelope/");
            XmlElement element2 = document.CreateElement(methodName);
            element2.SetAttribute("xmlns", xmlNS);
            if (!paras.IsNull() && (paras.Count != 0))
            {
                foreach (string str in paras.Keys)
                {
                    XmlElement element3 = document.CreateElement(str);
                    element3.InnerText = paras[str].ToString();
                    element2.AppendChild(element3);
                }
            }
            element.AppendChild(element2);
            document.DocumentElement.AppendChild(element);
            return Encoding.UTF8.GetBytes(document.OuterXml);
        }

        public static string GetWebService(string url, string methodName, Hashtable parms)
        {
            string str = (parms.IsNull() || (parms.Count == 0)) ? string.Empty : ("?" + parms.ToUrl());
            return HttpHelper.SendGet(url + "/" + methodName + str, "application/x-www-form-urlencoded", CredentialCache.DefaultCredentials, 0x4e20).ToXmlDOM().InnerText;
        }

        private static string GetWsClassName(string wsUrl)
        {
            string[] strArray = wsUrl.Split(new char[] { '/' });
            return strArray[strArray.Length - 1].Split(new char[] { '.' })[0];
        }

        public static Type GetWsProxyType(string wsUrl, string classname)
        {
            string name = "Pub.Class.WebServiceHelper.DynamicWebCalling";
            if (classname.IsNull() || (classname == ""))
            {
                classname = GetWsClassName(wsUrl);
            }
            string key = wsUrl + "@" + classname;
            if (WSProxyTypeDictionary.ContainsKey(key))
            {
                return WSProxyTypeDictionary[key];
            }
            WebClient client = new WebClient();
            ServiceDescription serviceDescription = ServiceDescription.Read(client.OpenRead(wsUrl + "?WSDL"));
            ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
            importer.AddServiceDescription(serviceDescription, "", "");
            CodeNamespace namespace2 = new CodeNamespace(name);
            CodeCompileUnit codeCompileUnit = new CodeCompileUnit();
            codeCompileUnit.Namespaces.Add(namespace2);
            importer.Import(namespace2, codeCompileUnit);
            ICodeCompiler compiler = new CSharpCodeProvider().CreateCompiler();
            CompilerParameters options = new CompilerParameters {
                GenerateExecutable = false,
                GenerateInMemory = true
            };
            options.ReferencedAssemblies.Add("System.dll");
            options.ReferencedAssemblies.Add("System.XML.dll");
            options.ReferencedAssemblies.Add("System.Web.Services.dll");
            options.ReferencedAssemblies.Add("System.Data.dll");
            CompilerResults results = compiler.CompileAssemblyFromDom(options, codeCompileUnit);
            if (results.Errors.HasErrors)
            {
                StringBuilder builder = new StringBuilder();
                foreach (CompilerError error in results.Errors)
                {
                    builder.Append(error.ToString());
                    builder.Append(Environment.NewLine);
                }
                throw new Exception(builder.ToString());
            }
            Type type = results.CompiledAssembly.GetType(name + "." + classname, true, true);
            if (!WSProxyTypeDictionary.ContainsKey(key))
            {
                WSProxyTypeDictionary.Add(key, type);
            }
            return type;
        }

        public static object InvokeWebService(string wsUrl, string methodname, object[] args)
        {
            return InvokeWebService(wsUrl, null, methodname, args);
        }

        public static object InvokeWebService(string wsUrl, string classname, string methodname, object[] args)
        {
            object obj3;
            try
            {
                Type wsProxyType = GetWsProxyType(wsUrl, classname);
                object obj2 = Activator.CreateInstance(wsProxyType);
                obj3 = wsProxyType.GetMethod(methodname).Invoke(obj2, args);
            }
            catch (Exception exception)
            {
                throw exception;
            }
            return obj3;
        }

        public static string PostWebService(string url, string methodName, Hashtable parms)
        {
            return HttpHelper.SendPost(url + "/" + methodName, parms.ToUrl(), "application/x-www-form-urlencoded", CredentialCache.DefaultCredentials, 0x4e20).ToXmlDOM().InnerText;
        }

        public static string SoapWebService(string url, string methodName, Hashtable parms)
        {
            string xmlNS = string.Empty;
            if (!_xmlNamespaces.ContainsKey(url))
            {
                HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url + "?WSDL");
                request.Credentials = CredentialCache.DefaultCredentials;
                request.ServicePoint.Expect100Continue = false;
                request.Timeout = 0x4e20;
                StreamReader reader = new StreamReader(request.GetResponse().GetResponseStream(), Encoding.UTF8);
                XmlDocument document = new XmlDocument();
                document.LoadXml(reader.ReadToEnd());
                xmlNS = document.SelectSingleNode("//@targetNamespace").Value;
                _xmlNamespaces[url] = xmlNS;
            }
            else
            {
                xmlNS = _xmlNamespaces[url].ToString();
            }
            HttpWebRequest request2 = (HttpWebRequest) WebRequest.Create(url);
            request2.Method = "POST";
            request2.ContentType = "text/xml; charset=utf-8";
            request2.Headers.Add("SOAPAction", "\"" + xmlNS + (xmlNS.EndsWith("/") ? "" : "/") + methodName + "\"");
            request2.Credentials = CredentialCache.DefaultCredentials;
            request2.Timeout = 0x4e20;
            request2.ServicePoint.Expect100Continue = false;
            byte[] buffer = EncodeParamsToSoap(parms, xmlNS, methodName);
            request2.ContentLength = buffer.Length;
            Stream requestStream = request2.GetRequestStream();
            requestStream.Write(buffer, 0, buffer.Length);
            requestStream.Close();
            XmlDocument document2 = new XmlDocument();
            XmlDocument document3 = new XmlDocument();
            StreamReader reader2 = new StreamReader(request2.GetResponse().GetResponseStream(), Encoding.UTF8);
            string xml = reader2.ReadToEnd();
            reader2.Close();
            document2.LoadXml(xml);
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(document2.NameTable);
            nsmgr.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
            document3.LoadXml("<root>" + document2.SelectSingleNode("//soap:Body/*", nsmgr).InnerXml + "</root>");
            XmlDeclaration newChild = document3.CreateXmlDeclaration("1.0", "utf-8", null);
            document3.InsertBefore(newChild, document3.DocumentElement);
            return document3.InnerText;
        }
    }
}

